/*
 * File: vfsdriver.c
 *
 * Description: This is a driver program for testing your VFS system using an interaction script as input
 * You need to make additional calls to your respective functions as noted in the comments below
 * Make sure the output you display is exactly as per the given specifications for you. Do NOT print
 * any extra output (like debug messages) in the final version of your driver program. You can use this driver program
 * in a in incremental manner as you keep implementing one operator after another. For operators not yet implemented,
 * you can leave the output as given ("TO_BE_DONE"). So you can use this program as your "main" program for testing purposes.
 *
 * DO NOT write the full code for operators in the driver program! You must only CALL your functions from here.
 *
 * Usage: vfsdriver <scriptfilename>
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "../include/filedesc.h"
#include "../include/vfs.h"
#include "../include/narray.h"
#include "../include/vfs_errorcodes.h"
#include "../include/hash.h"
#include "../include/bst.h"
#include "../include/fileop.h"

#define BUFSIZE 200
#define CMDSIZE 200
#define PARSIZE 200



void createvfs ( char *P1, char *P2 );
void mountvfs ( char *P1 );
void unmountvfs ( char *P1 );
void makedir ( char *P1, char *P2 );
void deletedir ( char *P1 );
void movedir ( char *P1, char *P2 );
void listdir ( char *P1, int P2, char *P3 );
void addfile ( char *P1, char *P2, char *P3 );
void listfile ( char *P1, char *P2 );
void updatefile ( char *P1, char *P2 );
void removefile ( char *P1 );
void movefile ( char *P1, char *P2 );
void copyfile ( char *P1, char *P2 );
void exportfile ( char *P1, char *P2 );
void searchfile ( char *P1, char *P2 );

void processcommand( char *command, char *P1, char *P2, char *P3 );
FILE *fp1;
char msg[50];

int main( int argc, char *argv[] )
{
	FILE *scriptfp;
	fp1=fopen("output","w");
	
	if(fp1==NULL)
			printf("jfoir\n");
	char linebuffer[BUFSIZE];
	char command[CMDSIZE], par1[PARSIZE], par2[PARSIZE], par3[PARSIZE];
	char *token;
	
	if( argc != 2 ){
		fprintf(stderr,"Usage: vfsdriver <scriptfile>\n");
		return(1);
	}

	if( (scriptfp=fopen(argv[1],"r")) == NULL ){
		fprintf(stderr,"Unable to open script file: %s\n", argv[1]);
		return(2);
	}

	while( fgets(linebuffer, sizeof(linebuffer), scriptfp) != NULL ){
		//This output is for debugging... do not uncomment in final version */
		
		//printf("==================================================\n");
		//printf("Processing: %s\n", linebuffer);
	//	printf("==================================================\n");
		/* Remove the extra newline character in the end of line */
		linebuffer[ strlen(linebuffer)-1 ] = '\0';
		
		/* Get the command and the parameters using tokenizer */
		strcpy( command, (token = strtok(linebuffer, " ")) == NULL ? "" : token );
		
		strcpy( par1, (token = strtok(NULL, " ")) == NULL ? "" : token );
		strcpy( par2, (token = strtok(NULL, " ")) == NULL ? "" : token );
		strcpy( par3, (token = strtok(NULL, " ")) == NULL ? "" : token );
		 //printf("Command:%s:p1:%s:p2:%s:p3:%s\n",command, par1, par2, par3); 
		processcommand( command, par1, par2, par3 );
	}
	
}

void processcommand( char *command, char *P1, char *P2, char *P3 )
{
	if( strcmp(command, "createvfs") == 0 ){
		
		createvfs(P1,P2);
	}
	else if( strcmp(command, "mountvfs") == 0 )
		mountvfs (P1);
	else if( strcmp(command, "unmountvfs") == 0 )
		unmountvfs (P1);
	else if( strcmp(command, "makedir") == 0 )
		makedir (P1,P2);
	else if( strcmp(command, "deletedir") == 0 ){

               deletedir (P1);
                 }

		
	else if( strcmp(command, "movedir") == 0 )
		movedir (P1,P2);
	else if( strcmp(command, "listdir") == 0 ){
		int flag = atoi(P2);
		listdir (P1,flag,P3);
	}
	else if( strcmp(command, "addfile") == 0 )
		addfile (P1,P2,P3);
	else if( strcmp(command, "listfile") == 0 )
		listfile (P1,P2);
	else if( strcmp(command, "updatefile") == 0 )
		updatefile (P1,P2);
	else if( strcmp(command, "removefile") == 0 )
		removefile (P1);
	else if( strcmp(command, "movefile") == 0 )
		movefile (P1,P2);
	else if( strcmp(command, "copyfile") == 0 )
		copyfile (P1,P2);
	else if( strcmp(command, "exportfile") == 0 )
		exportfile (P1,P2);
	else if( strcmp(command, "searchfile") == 0 )
		searchfile (P1,P2);
	else
		printf("Ignoring invalid command %s\n", command);
		
}

void createvfs ( char *P1, char *P2 )
{	
        //printf("%d is int\n",P2);
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0 )
	{	int size = atoi(P2);
                strcpy(msg,create (P1,size));
                printf("%s\n",msg);
                fprintf(fp1,"%s\n",msg);
                }
         else
         {
          	strcpy(msg,"createvfs_FAILURE ");
          	strcat(msg,ERR_VFS_CREATE_00 );
          	 printf("%s\n",msg);
        	fprintf(fp1,"%s\n",msg); 
         
         }       
                
                     
}

void mountvfs ( char *P1 )
{
          
         if(strcmp(P1,"\0")!=0){
         	/* Call the appropriate function with given arguments and display appropriate output on th*/
         strcpy(msg,mount(P1));
         printf("%s\n",msg);
         fprintf(fp1,"%s\n",msg);
         }
         else{
         	strcpy(msg,"mountvfs_FAILURE");
          	strcat(msg, ERR_VFS_CREATE_00);
          	printf("%s\n",msg);
        	fprintf(fp1,"%s\n",msg); 
         }
            
	 
}

void unmountvfs ( char *P1 )
{       
        if(strcmp(P1,"\0")!=0){ 
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
        strcpy(msg,unmount(P1));
        fprintf(fp1,"%s\n",msg);
        }
         else{
         	strcpy(msg,"unmountvfs_FAILURE ");
          	strcat(msg,ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg);  
        	printf("%s\n",msg);
         }
         
        
}
	


void makedir ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("%c\n",P1[strlen(P1)-1]);
	if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0){
	if((strcmp(P1,"/")==0)&&(strcmp(P2,"/")==0))
	{
		strcpy(msg,"makedir_FAILURE ");
	        strcat(msg,ERR_VFS_MAKEDIR_03);
	   	fprintf(fp1,"%s\n",msg);
		 printf("%s\n",msg);
		}
	if(P1[strlen(P1)-1]!='/')
	 {
	 strcat(P1,"/");
	 strcat(P1,P2);
	 //printf("%s\n",P1);
	 }
	 else{
	strcat(P1,P2);
	 //printf("%s\n",P1);
	}
	
        if(strlen(labels)==0)
 		{
 		strcpy(msg,"makedir_FAILURE ");
	    	strcat(msg,ERR_VFS_MAKEDIR_05);
	    	fprintf(fp1,"%s\n",msg);
	    	printf("%s\n",msg);
	    	}
        
        else if(strpbrk (P2,"/"))                       //checks if vfs name contains /
		{
		strcpy(msg,"makedir_FAILURE ");
	        strcat(msg,ERR_VFS_MAKEDIR_02);
		 printf("%s\n",msg);	       
	        fprintf(fp1,"%s\n",msg);
               }
      
	else  
		{
	     	strcpy(msg,makedirectory(&root,P2,P1));
	     	//print_inorder(bst_root);
        	fprintf(fp1,"%s\n",msg); 
        	printf("%s\n",msg);
		}
	}
    else{
    		strcpy(msg,"makedir_FAILURE ");
          	strcat(msg,ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg); 
    		 printf("%s\n",msg);
    
    }
	
}

void deletedir ( char *P1 )
{  
	if(strcmp(P1,"\0")!=0 ){
	if(strlen(labels)==0)
 		{
  		strcpy(msg,"deletedir_FAILURE ");
	    	strcat(msg,ERR_VFS_DELETEDIR_04);
	    	 printf("%s\n",msg);
	    	fprintf(fp1,"%s\n",msg);
	    	}    
	else{
	strcpy(msg,deletenodes(&root,P1));
	printf("%s\n",msg);
	fprintf(fp1,"%s\n",msg);
        }
          
	}
	else{
	
		strcpy(msg,"deletedir_FAILURE ");
          	strcat(msg, ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg); 
	
	}
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	

}

void movedir ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	int i,flag=0;
        
	if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0){
		if(P1[strlen(P1)-1]=='/')
              		P1[strlen(P1)-1]='\0';
        	if(P2[strlen(P2)-1]=='/')
              		P2[strlen(P2)-1]='\0';
	if(strlen(labels)==0)
 		{
 		strcpy(msg,"movdir_FAILURE ");
	    	strcat(msg,ERR_VFS_DELETEDIR_04);
	    	 printf("%s\n",msg);
	    	fprintf(fp1,"%s\n",msg);
	    	}  
	else 
	{
		for(i=0;P1[i]!='\0';i++)
		{
			if(P1[i]!=P2[i])
	       		{
		 		flag=1;
		 		break;
	       		}
		}
		if(flag==0)
		{
		strcpy(msg,"movedir_FAILURE ");
	    	strcat(msg,ERR_VFS_MOVEDIR_06);
	    	fprintf(fp1,"%s\n",msg);
	    	 printf("%s\n",msg);	
		
		}
	 
		else
		{
		strcpy(msg,movdir(P1,P2,root));
		fprintf(fp1,"%s\n",msg);	
		printf("%s\n",msg);	
		//print_inorder(bst_root);
                }      
        }
        }
        else{
        	strcpy(msg,"movedir_FAILURE ");
          	strcat(msg,ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg);
        	 printf("%s\n",msg);
        	 } 
}

void listdir ( char *P1, int P2, char *P3 )
{
       if(strcmp(P1,"\0")!=0 && strcmp(P3,"\0")!=0){

		if(strlen(labels)==0)
 		{
 		strcpy(msg,"listdir_FAILURE ");
	    	strcat(msg,ERR_VFS_LISTDIR_03);
	    	fprintf(fp1,"%s\n",msg);
	    	printf("%s\n",msg);
	    	}
		else{
       		strcpy(msg,listdirc(P1,P2,P3));
       		fprintf(fp1,"%s\n",msg);
       		printf("%s\n",msg); 
		}
       }
       else{
       		strcpy(msg,"listdir_FAILURE ");
          	strcat(msg,ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg); 
        	 printf("%s\n",msg);
        	}
}

void addfile ( char *P1, char *P2, char *P3 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
        /*if(P1=NULL || P2==NULL ||P3==NULL)
        {
           fprintf(fp1,"VFS_INSUFFICIENT_ARGUMENTS");
        }
       else{*/
       if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0 && strcmp(P3,"\0")!=0){
		strcpy(msg,addfiles(P1,P2,P3));
        	fprintf(fp1,"%s\n",msg);
         	printf("%s\n",msg);
         	}
       else{
       		strcpy(msg,"addfile_FAILURE ");
          	strcat(msg, ERR_VFS_CREATE_00);
        	printf("%s\n",msg);
        	fprintf(fp1,"%s\n",msg); 
        	}
}     

void listfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0){
		strcpy(msg,listfiles(P1,P2));
        	fprintf(fp1,"%s\n",msg);
        	printf("%s\n",msg);
        	}
         else{
       		strcpy(msg,"listfile_FAILURE ");
          	strcat(msg,ERR_VFS_CREATE_00 );
        	fprintf(fp1,"%s\n",msg); 
        	printf("%s\n",msg);
        	}

}

void updatefile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("updatefile_TO_BE_DONE\n");
       /* strcpy(msg,updatefiles(P1,P2));
        fprintf(fp1,"%s\n",msg);*/
        if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0){
        	strcpy(msg,updatefiles(P1,P2));
        	fprintf(fp1,"%s\n",msg);
        	printf("%s\n",msg);
        	}
         else{
       		strcpy(msg,"updatefile_FAILURE ");
          	strcat(msg,ERR_VFS_CREATE_00 );
        	fprintf(fp1,"%s\n",msg); 
        	printf("%s\n",msg);
        	}
}

void removefile ( char *P1 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	/*strcpy(msg,removefiles(P1));
        fprintf(fp1,"%s\n",msg);*/
        if(strcmp(P1,"\0")!=0){
        	strcpy(msg,removefiles(P1));
        	fprintf(fp1,"%s\n",msg);
        	printf("%s\n",msg);
        	}
         else{
       		strcpy(msg,"removefile_FAILURE ");
          	strcat(msg, ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg); 
        	printf("%s\n",msg);
        	}

}

void movefile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0){
	//printf("movefile_TO_BE_DONE\n");
		strcpy(msg,movefiles(P1,P2));
        	fprintf(fp1,"%s\n",msg);
        	printf("%s\n",msg);
        }
         else{
       		strcpy(msg,"movefile_FAILURE "); 
       	      	strcat(msg,ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg); 
        	printf("%s\n",msg);
        	}
}

void copyfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
	//printf("copyfile_TO_BE_DONE\n");
	if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0){
      		strcpy(msg,copyfiles(P1,P2));
        	fprintf(fp1,"%s\n",msg);
        	printf("%s\n",msg);
        	}
         else{
       		strcpy(msg,"copyfile_FAILURE ");
          	strcat(msg, ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg); 
        	printf("%s\n",msg);
        	}
}

void exportfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */            
        if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0){
        	 strcpy(msg,exportfiles(P1,P2));
       		 fprintf(fp1,"%s\n",msg);
        	 printf("%s\n",msg);
        	}
         else{
       		strcpy(msg,"exportfile_FAILURE ");
          	strcat(msg,ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg); 
		printf("%s\n",msg);
        	}

}

void searchfile ( char *P1, char *P2 )
{
	/* Call the appropriate function with given arguments and display appropriate output on the screen */
//	printf("searchfile_TO_BE_DONE\n");

	if(strcmp(P1,"\0")!=0 && strcmp(P2,"\0")!=0){
		strcpy(msg,searchfiles(P1,P2));
	        fprintf(fp1,"%s\n",msg);
		printf("%s\n",msg);
	        }
        else{
        	strcpy(msg,"searchfile_FAILURE ");
          	strcat(msg, ERR_VFS_CREATE_00);
        	fprintf(fp1,"%s\n",msg); 
        	printf("%s\n",msg);
        	}
   

}



